/**
 * BaseForm.java 
 * Copyright © 2014-2016, 杭州泊享网络科技有限公司
 * 
 * @author Liu Tao
 * @create 2015年5月22日
 */
package com.pshare.framework.form;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.pshare.constant.SeaxConstants;
import com.pshare.framework.annotation.SignCheck;
import com.pshare.tool.SessionTool;
import com.pshare.util.EncodeUtils;
import com.pshare.util.StringUtils;

/**
 * 基础表单类
 */
public class BaseForm {

	@SignCheck
	public String getSign() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		String sign = request.getHeader("sign");
		if (StringUtils.isBlank(sign)) {
			return "false";
		}
		
		// 操作用户的ID，如未登录，则用默认字符串表示
		Long userId = SessionTool.getUserId();
		String uid = userId == null ? SeaxConstants.VALUE_DEFAULT_USER_ID : userId + SeaxConstants.EMPTY;

		Map<String, String> map = getFieldMap();
		map.put("uid", uid);

		StringBuilder str = new StringBuilder();
		for (String key : map.keySet()) {
			str.append(key).append(map.get(key));
		}

		String calculatedSign = EncodeUtils.encodeByMD5(str.toString());
		return calculatedSign.equals(sign) + SeaxConstants.EMPTY;
	}

	/**
	 * 获取除sign字段外的所有基本类型及其包装类型参数和字符串、字符串数组类型参数组成 参数名:值 的正序map
	 * @return Map<String, String>
	 */
	private Map<String, String> getFieldMap() {
		Map<String, String> map = new TreeMap<String, String>();
		Field[] fields = getClass().getDeclaredFields();
		try {
			for (Field field : fields) {
				String fieldName = field.getName();
				String filedValue = null;
				if (SeaxConstants.KEY_SIGN_DATA.equals(fieldName)) {
					continue;
				}
				field.setAccessible(true);
				Object valueObj = field.get(this);
				if (valueObj == null || valueObj.toString().length() == 0) {
					continue;
				}

				if (field.getType().isPrimitive()) {
					filedValue = valueObj + SeaxConstants.EMPTY;
				} else if (valueObj instanceof String) {
					filedValue = StringUtils.trimToEmpty(valueObj);
				} else if (valueObj instanceof String[]) {
					String[] values = (String[]) valueObj;
					for (int i = 0; i < values.length; i++) {
						filedValue = StringUtils.trimToEmpty(values[i]) + ",";
					}
					int len = filedValue.length();
					if (len > 0) {
						filedValue = filedValue.substring(0, len - 1);
					}
				} else if (valueObj instanceof Number || valueObj instanceof Boolean || valueObj instanceof Character) {
					filedValue = valueObj + SeaxConstants.EMPTY;
				} else {
					// 不参与签名
					continue;
				}

				map.put(fieldName, filedValue);
			}
		} catch (IllegalArgumentException | IllegalAccessException e) {
			e.printStackTrace();
		}
		return map;
	}

}
